/*
 *  Copyright (C) 2010-2012 Taylor Leese (tleese22@gmail.com)
 *
 *  This file is part of jappstart.
 *
 *  jappstart is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  jappstart is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with jappstart.  If not, see <http://www.gnu.org/licenses/>.
 */
package wendyeq.iweb.blog.service.impl;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
//import javax.persistence.EntityManager;
//import javax.persistence.NoResultException;
//import javax.persistence.PersistenceContext;
//import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import wendyeq.iweb.blog.dao.IUserAccountDAO;
import wendyeq.iweb.blog.dao.impl.UserAccountDAO;
import wendyeq.iweb.blog.pojo.UserAccount;
import wendyeq.iweb.blog.service.EnhancedUserDetailsService;
import wendyeq.iweb.blog.vo.EnhancedUser;

import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;


/**
 * The user details service implementation.
 */
@Service("userDetailsService")
public class UserDetailsServiceImpl implements EnhancedUserDetailsService {
	private static final Logger logger = Logger
	.getLogger(UserDetailsServiceImpl.class);

	/**
	 * The default cache expiration in seconds.
	 */
	private static final int DEFAULT_EXPIRATION = 3600;
//	@Resource(name="userAccountDAO")
	private UserAccountDAO userAccountDAO ;
	
	public UserAccountDAO getUserAccountDAO() {
		return userAccountDAO;
	}
	public void setUserAccountDAO(UserAccountDAO userAccountDAO) {
		this.userAccountDAO = userAccountDAO;
	}

	/**
	 * The username field name.
	 */
	private static final String USERNAME = "username";

	/**
	 * The select user query.
	 */
	private static final String SELECT_USER =
		"SELECT u FROM UserAccount u WHERE username = :username";

	/**
	 * The entity manager.
	 */
//	@PersistenceContext
//	private transient EntityManager entityManager;

	//    /**
	//     * The mail task name.
	//     */
	//    private String mailTaskName;
	//
	//    /**
	//     * The mail task URL.
	//     */
	//    private String mailTaskUrl;

	/**
	 * The datastore service.
	 */
//	private DatastoreService datastoreService;

	/**
	 * The memcache service.
	 */
//	private MemcacheService memcacheService;

	/**
	 * Returns the mail task name.
	 *
	 * @return the mail task name
	 */
	//    public final String getMailTaskName() {
	//        return mailTaskName;
	//    }

	/**
	 * Sets the mail task name.
	 *
	 * @param mailTaskName the mail task name
	 */
	//    public final void setMailTaskName(final String mailTaskName) {
	//        this.mailTaskName = mailTaskName;
	//    }

	/**
	 * Returns the mail task URL.
	 *
	 * @return the mail task URL
	 */
	//    public final String getMailTaskUrl() {
	//        return mailTaskUrl;
	//    }

	/**
	 * Sets the mail task URL.
	 *
	 * @param mailTaskUrl the mail task URL
	 */
	//    public final void setMailTaskUrl(final String mailTaskUrl) {
	//        this.mailTaskUrl = mailTaskUrl;
	//    }

	/**
	 * Returns the datastore service.
	 *
	 * @return the datastore service
	 */
//	public final DatastoreService getDatastoreService() {
//		return datastoreService;
//	}

	/**
	 * Sets the datastore service.
	 *
	 * @param datastoreService the datastore service
	 */
//	public final void setDatastoreService(
//			final DatastoreService datastoreService) {
//		this.datastoreService = datastoreService;
//	}

	/**
	 * Returns the memcache service.
	 *
	 * @return the memcache service
	 */
	public final MemcacheService getMemcacheService() {
		return MemcacheServiceFactory.getMemcacheService();
	}


	/**
	 * Locates the user based on the username.
	 *
	 * @param username string the username
	 * @return the user details
	 */
	@Override
	public final UserDetails loadUserByUsername(final String username) {
		final List<GrantedAuthority> authorities =
			new ArrayList<GrantedAuthority>();
		UserAccount user = (UserAccount) MemcacheServiceFactory.getMemcacheService().get(username);
		//        UserService us = UserServiceFactory.getUserService();
		//        User guser=us.getCurrentUser();
		//        if(guser==null||!"chch1020@gmail.com".equals(guser.getEmail())){
		//        	logger.info("当前用户不可用！！！");
		//        	throw new UsernameNotFoundException("Username not found.", new NoResultException());
		//        }
		if (user == null) {
			user =userAccountDAO.findByName(username);
			MemcacheServiceFactory.getMemcacheService().put(username, user,
					Expiration.byDeltaSeconds(DEFAULT_EXPIRATION));
		}

		authorities.add(new SimpleGrantedAuthority(user.getRole()));

		return new EnhancedUser(user.getUsername(), user.getEmail(),
				user.getDisplayName(), user.getPassword(), user.getSalt(),
				user.isEnabled(), user.isAccountNonExpired(),
				user.isCredentialsNonExpired(), user.isAccountNonLocked(),
				authorities);
	}

	/**
	 * Returns the user account for the given username.
	 *
	 * @param username the username
	 * @return the user account
	 */
	@Override
	public final UserAccount getUser(final String username) {
		UserAccount user = (UserAccount) getMemcacheService().get(username);

		if (user == null) {
			user =userAccountDAO.findByName(username);
			MemcacheServiceFactory.getMemcacheService().put(username, user,
					Expiration.byDeltaSeconds(DEFAULT_EXPIRATION));
		}

		return user;
	}


	/**
	 * Activates the user with the given activation key.
	 *
	 * @param key the activation key
	 * @return true if successful; false otherwise
	 */
	@Override
	@Transactional
	public final boolean activateUser(final String key) {
//		final Query query = entityManager.createQuery(
//		"SELECT u FROM UserAccount u WHERE activationKey = :key");
//		query.setParameter("key", key);

//		try {
//			final UserAccount user = (UserAccount) query.getSingleResult();
//			user.setEnabled(true);
//
//			entityManager.persist(user);
//
//			getMemcacheService().put(user.getUsername(), user,
//					Expiration.byDeltaSeconds(DEFAULT_EXPIRATION));
//
//			return true;
//		} catch (NoResultException e) {
//			return false;
//		}
		return true;
	}

	/**
	 * Indicates if the activation e-mail has been sent.
	 *
	 * @param username the username
	 * @return true if sent; false otherwise
	 */
	@Override
	public final boolean isActivationEmailSent(final String username) {
//		UserAccount user = (UserAccount) getMemcacheService().get(username);
//
//		if (user == null) {
//			final Query query = entityManager.createQuery(SELECT_USER);
//			query.setParameter(USERNAME, username);
//
//			try {
//				user = (UserAccount) query.getSingleResult();
//
//				getMemcacheService().put(username, user,
//						Expiration.byDeltaSeconds(DEFAULT_EXPIRATION));
//			} catch (NoResultException e) {
//				throw new UsernameNotFoundException("Username not found.", e);
//			}
//		}
//
//		return user.isActivationEmailSent();
		return true;
	}

	/**
	 * Updates the activation e-mail sent status.
	 *
	 * @param username the username
	 */
	@Override
	@Transactional
	public final void activationEmailSent(final String username) {
//		final Query query = entityManager.createQuery(SELECT_USER);
//		query.setParameter(USERNAME, username);
//
//		try {
//			final UserAccount user = (UserAccount) query.getSingleResult();
//			user.setActivationEmailSent(true);
//
//			entityManager.persist(user);
//
//			getMemcacheService().put(user.getUsername(), user,
//					Expiration.byDeltaSeconds(DEFAULT_EXPIRATION));
//		} catch (NoResultException e) {
//			throw new UsernameNotFoundException("Username not found.", e);
//		}
	}

}
